﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using QFlow.Data;
using QFlow.Core;

namespace QFlow.Windows.Forms
{
    public partial class NewSalesOrderItem : Utils.BaseForm
    {
        bool _New, _Change = false, _ComboLoaded = false;
        SaleOrder _sOrder;
        SaleItem _sItem;
        double _PurchaseUnitPrice, _SalesUnitPrice;
        List<PurchaseItem> _AvailableItems;
        List<double> _AvailableQuantites;

        /// <summary>
        /// Initializes a new instance of the <see cref="NewSalesOrderItem"/> class.
        /// </summary>
        /// <param name="sOrder">The s order.</param>
        /// <param name="context">The context.</param>
        public NewSalesOrderItem(SaleOrder sOrder, QFlowDbContext context)
            : base(context)
        {
            InitializeComponent();
            _sOrder = sOrder;
            _New = true;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="NewSalesOrderItem"/> class.
        /// </summary>
        /// <param name="sOrder">The s order.</param>
        /// <param name="sItem">The s item.</param>
        /// <param name="context">The context.</param>
        public NewSalesOrderItem(SaleOrder sOrder, SaleItem sItem, QFlowDbContext context)
            : base(context)
        {
            InitializeComponent();
            _sOrder = sOrder;
            _New = false;
            _sItem = sItem;
            this.Text = QFlow.Windows.Properties.Resources.FRMEditSItem;
        }

        /// <summary>
        /// Handles the Load event of the NewSalesOrderItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void NewSalesOrderItem_Load(object sender, EventArgs e)
        {
            cmbProducts.DataSource = this.Context.Products.Where(product => !product.IsNonStockable).ToArray();
            cmbProducts.SelectedIndex = -1;
            if (!_New)
            {
                _ComboLoaded = true;
                cmbProducts.SelectedValue = _sItem.ProductID;
                txtQuantity.Text = _sItem.Quantity.ToString("F");
                txtUnitPrice.Text = _sItem.UnitPrice.ToString("F");
                txtTaxesPercent.Text = _sItem.TaxesPercent.ToString("F");
                txtNotes.Text = _sItem.Notes;
            }
            else _ComboLoaded = true;
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event of the cmbProducts control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void cmbProducts_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_ComboLoaded)
            {
                if (cmbProducts.SelectedIndex != -1)
                {
                    grpPrice.Enabled = true;
                    Product product = cmbProducts.SelectedItem as Product;

                    _PurchaseUnitPrice = product.StockableProduct.PurchaseUnitPrice;
                    _SalesUnitPrice = product.StockableProduct.SalesUnitPrice;

                    var items = Context.PurchaseItems.Where(item => item.ProductID == product.ProductID).OrderBy(item => item.ExpirationDate);
                    SaleOrderManager.GetAvailableItems(product.ProductID, out _AvailableItems, out _AvailableQuantites);
                    if (!_New)
                    {
                        if (_AvailableItems.Count == 0)
                        {
                            _AvailableItems.Add(_sItem.PurchaseItem);
                            _AvailableQuantites.Add(_sItem.Quantity);
                        }
                        else
                        {
                            for (int i = 0; i < _AvailableItems.Count; i++)
                            {
                                if (_AvailableItems[i].PurchaseItemID == _sItem.PurchaseItemId)
                                {
                                    _AvailableQuantites[i] += _sItem.Quantity;
                                    break;
                                }
                            }
                        }
                    }
                    if (_AvailableItems.Count == 0)
                    {
                        txtAvailableQuantity.Text = "0";
                        MessageBox.Show("There are not any available items to sell for the selected product.", QFlow.Windows.Properties.Resources.MBErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        txtQuantity.Text = "0";
                        txtQuantity.Enabled = false;
                    }
                    else txtQuantity.Enabled = true;

                    cmbExpirationDates.DataSource = _AvailableItems;
                    txtPurchasePrice.Text = _PurchaseUnitPrice.ToString("F");
                    txtTaxesPercent.Text = product.StockableProduct.TaxesPercent.ToString("F");
                    txtSalesPrice.Text = product.StockableProduct.SalesUnitPrice.ToString("F");
                    txtUnitPrice.Text = _SalesUnitPrice.ToString("F");
                }
                else cmbExpirationDates.DataSource = null;
            }
        }

        private void cmbExpirationDates_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbExpirationDates.SelectedIndex != -1)
            {
                txtAvailableQuantity.Text = _AvailableQuantites[cmbExpirationDates.SelectedIndex].ToString();
            }
        }

        /// <summary>
        /// Handles the TextChanged event of the txtUnitPrice control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void txtUnitPrice_TextChanged(object sender, EventArgs e)
        {
            if (!_Change)
            {
                _Change = true;
                double unitPrice = 0.0;
                if (double.TryParse(txtUnitPrice.Text, out unitPrice))
                {
                    double profit = SaleOrderManager.CalculateProfitPercent(_PurchaseUnitPrice, unitPrice);
                    double discount = SaleOrderManager.CaluclateItemDiscount(_SalesUnitPrice, unitPrice);
                    txtProfitPercent.Text = profit.ToString("F");
                    txtDiscountPercent.Text = discount.ToString("F");
                    CalculateTotalValue();
                }
                _Change = false;
            }
        }

        /// <summary>
        /// Handles the TextChanged event of the txtProfitPercent control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void txtProfitPercent_TextChanged(object sender, EventArgs e)
        {
            if (!_Change)
            {
                _Change = true;
                double profit = 0.0;
                if (double.TryParse(txtProfitPercent.Text, out profit))
                {
                    double unitPrice = SaleOrderManager.CalculateProfitValue(profit, _PurchaseUnitPrice) + _PurchaseUnitPrice;
                    double discount = SaleOrderManager.CaluclateItemDiscount(_SalesUnitPrice, unitPrice);
                    txtUnitPrice.Text = unitPrice.ToString("F");
                    txtDiscountPercent.Text = discount.ToString("F");
                    CalculateTotalValue();
                }
                _Change = false;
            }
        }

        /// <summary>
        /// Handles the TextChanged event of the txtDiscountPercent control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void txtDiscountPercent_TextChanged(object sender, EventArgs e)
        {
            if (!_Change)
            {
                _Change = true;
                double discount = 0.0;
                if (double.TryParse(txtDiscountPercent.Text, out discount))
                {
                    double unitPrice = _SalesUnitPrice - SaleOrderManager.CalculateDicountValue(discount, _SalesUnitPrice);
                    double profit = SaleOrderManager.CalculateProfitPercent(_PurchaseUnitPrice, unitPrice);
                    txtUnitPrice.Text = unitPrice.ToString("F");
                    txtProfitPercent.Text = profit.ToString("F");
                    CalculateTotalValue();
                }
                _Change = false;
            }
        }

        /// <summary>
        /// Calculates the total value.
        /// </summary>
        private void CalculateTotalValue()
        {
            double quantity = 0.0, unitPrice = 0.0;
            if (double.TryParse(txtQuantity.Text, out quantity) && double.TryParse(txtUnitPrice.Text, out unitPrice))
            {
                txtValue.Text = (quantity * unitPrice).ToString("F");
            }
        }

        /// <summary>
        /// Handles the TextChanged event of the txtQuantity control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void txtQuantity_TextChanged(object sender, EventArgs e)
        {
            CalculateTotalValue();
        }

        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (superValidator1.Validate())
            {
                if (cmbProducts.SelectedIndex != -1)
                {
                    double quantity = double.Parse(txtQuantity.Text);
                    StockableProduct p = (cmbProducts.SelectedItem as Product).StockableProduct;
                    double availableQuantity = _AvailableQuantites[cmbExpirationDates.SelectedIndex];

                    if (!SaleOrderManager.CheckProductStatus(p, quantity, availableQuantity, _sOrder))
                        return;

                    if (_New)
                    {
                        SaleOrderManager.CreateSaleItem(quantity, double.Parse(txtUnitPrice.Text),
                            p, double.Parse(txtDiscountPercent.Text),
                            double.Parse(txtProfitPercent.Text), double.Parse(txtTaxesPercent.Text),
                            txtNotes.Text, _AvailableItems[cmbExpirationDates.SelectedIndex], _sOrder);
                    }
                    else
                    {
                        SaleOrderManager.UpdateSaleItem(_sItem, quantity, double.Parse(txtUnitPrice.Text),
                            p, double.Parse(txtDiscountPercent.Text),
                            double.Parse(txtProfitPercent.Text), double.Parse(txtTaxesPercent.Text),
                            txtNotes.Text, _AvailableItems[cmbExpirationDates.SelectedIndex]);
                    }

                    this.Close();
                }
                else
                {
                    MessageBox.Show(QFlow.Windows.Properties.Resources.MBChooseProduct, QFlow.Windows.Properties.Resources.MBErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
            }
        }

        /// <summary>
        /// Handles the Click event of the btnCancel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (_sItem != null)
            {
                if (_sItem.IsAttached())
                {
                    this.Context.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, _sItem);
                }
            }
            this.Close();
        }

        /// <summary>
        /// Raises the <see cref="E:Activated"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected override void OnActivated(EventArgs e)
        {

        }
    }
}
